package com.huxiu.yd.net;

/**
 * Created by tian on 14-1-2.
 */

import com.huxiu.yd.utils.Constants;
import com.huxiu.yd.utils.Global;
import com.huxiu.yd.utils.ImageUtils;
import com.huxiu.yd.utils.LogUtils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.json.JSONObject;

import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.Config;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by tian on 13-8-9.
 */
public class NetUtils {

    protected String path;

    protected Map<String, String> map;

    protected String cookie;

    protected Context context;

    protected boolean isCookie = true;

    protected HttpClient client;

    private static final String TAG = NetUtils.class.getName();

    public static final String HTTP_ERROR = "http_error";

    public static final String HTTP_IO_ERROR = "http_io_error";

    public static int TIMEOUT_CONNECTION = 2 * 1000 * 60;

    public static int TIMEOUT_READ = 2 * 1000 * 60;

    public static HttpClient getHttpClient() {
        DefaultHttpClient client = new DefaultHttpClient();
        client.getParams().setParameter(
                CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);
        client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,
                TIMEOUT_READ);
        client.getParams()
                .setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
                        TIMEOUT_CONNECTION);
        return client;
    }

    public NetUtils(Context context, Map<String, String> map, String path) {
        init(context, map, path);
    }

    public NetUtils(Context context, String path) {
        init(context, map, path);
    }

    private static void appendMapToUrlBuilder(StringBuilder sb, Map<String, String> map) {
        if ((map != null) && !map.isEmpty()) {
            sb.append("?");
            for (Map.Entry<String, String> entry : map.entrySet()) {
                if (!TextUtils.isEmpty(entry.getValue())) {
                    try {
                        sb.append(entry.getKey()).append("=")
                                .append(URLEncoder.encode(entry.getValue(), "utf-8"))
                                .append("&");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
            }
            sb.deleteCharAt(sb.length() - 1);
        }
    }


    private void init(Context context, Map<String, String> map, String path) {
        this.context = context;
        if (path.startsWith("http:") || path.startsWith("https:")) {
            this.path = path;
        } else {
            this.path = NetworkConstants.BASE_URL + path;
        }
        if (map != null) {
            this.map = map;
        }
    }

    public String getResult(InputStream inputStream) {
        String result = "";
        if (inputStream == null) {
            return result;
        }
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            String line = reader.readLine();
            while (line != null) {
                result += line;
                line = reader.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
            result = HTTP_IO_ERROR;
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
                result = HTTP_IO_ERROR;
            }
        }
        return result;
    }

    public boolean saveFile(String savePath, InputStream inputStream) {
        boolean flag = false;
        if (inputStream == null) {
            return false;
        }
        File storeFile = new File(savePath);
        FileOutputStream output = null;
        try {
            output = new FileOutputStream(storeFile);
            byte[] buf = new byte[1024];
            int ch;
            while ((ch = inputStream.read(buf)) != -1) {
                output.write(buf, 0, ch);
            }
            flag = true;
        } catch (IOException e) {
            e.printStackTrace();
            flag = false;
        } finally {
            try {
                inputStream.close();
                if (output != null) {
                    output.flush();
                    output.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return flag;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    protected HttpResponse postClient(HttpEntity entity) throws IOException {
        client = getHttpClient();
        HttpPost request = new HttpPost(path);
        LogUtils.d("NetUtils", "post to: " + path);
        request.setEntity(entity);
        if (isCookie) {
            request.setHeader("Cookie", cookie);
        }
        return client.execute(request);
    }

    protected HttpResponse getClient(String uri) throws IOException {
        client = getHttpClient();
        HttpGet request = new HttpGet(uri);
        LogUtils.d("NetUtils", "doGet, url is " + uri);
        if (isCookie) {
            request.setHeader("Cookie", cookie);
        }
        return client.execute(request);
    }

    public String doPost() {
        String result = "";
        try {
            List<NameValuePair> parameters = new ArrayList<NameValuePair>();
            if (map != null) {
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    if (TextUtils.isEmpty(entry.getValue())) {
                        continue;
                    }
                    NameValuePair nameValuePairs = new BasicNameValuePair(entry.getKey(),
                            entry.getValue());
                    parameters.add(nameValuePairs);
                }
            }
            HttpEntity entity = new UrlEncodedFormEntity(parameters, "UTF-8");
            if (Config.DEBUG) {
                HttpEntity entity2 = new UrlEncodedFormEntity(parameters,
                        "UTF-8");
                InputStream stream = entity2.getContent();
                try {
                    byte[] data = new byte[stream.available()];
                    stream.read(data);
                    String content = new String(data);
                    LogUtils.d(TAG, "post to url: " + path);
                    LogUtils.d(TAG, "post content is " + content);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            HttpResponse response = postClient(entity);
            int responseCode = response.getStatusLine().getStatusCode();
            LogUtils.d(TAG, "responseCode is " + responseCode);
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = response.getEntity().getContent();
                result = getResult(inputStream);
                LogUtils.d(TAG, "result is " + result);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            result = HTTP_ERROR;
            e.printStackTrace();
        } catch (IOException e) {
            result = HTTP_IO_ERROR;
            e.printStackTrace();
        } finally {
            try {
                client.getConnectionManager().shutdown();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public String downFile(String savePath) {
        String result = "";
        StringBuilder sb = new StringBuilder(path);
        try {
            appendMapToUrlBuilder(sb, map);
            String str = sb.toString();
            HttpResponse response = getClient(str);
            if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = response.getEntity().getContent();
                boolean flag = saveFile(savePath, inputStream);
                result = flag ? savePath : "";
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            result = HTTP_ERROR;
            e.printStackTrace();
        } catch (IOException e) {
            result = HTTP_IO_ERROR;
            e.printStackTrace();
        } finally {
            try {
                client.getConnectionManager().shutdown();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static Map<String, String> GetCommonMap(Context context, boolean needUserInfo) {
        Map<String, String> params = new LinkedHashMap<>();
        params.put("Appid", Constants.APP_ID);
        params.put("Appkey", Constants.APP_SECRET);
        params.put("mid", Global.DeviceUniqueID);
        params.put("platform", "android");
        params.put("client_ver", Global.version);
        if (needUserInfo && Global.user != null) {
            params.put("yd_auth", Global.user.yd_auth);
            params.put("yd_key", Global.user.yd_key);
            params.put("yd_uid", Global.user.user_id);
        }
        return params;
    }

    public static boolean isResultOk(JSONObject object) {
        try {
            String result = object.getString("result");
            return result.toLowerCase().contentEquals("ok");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    protected Map<String, Bitmap> imageEntities;

    public void setImageEntities(String key, Bitmap bitmap) {
        if (imageEntities == null) {
            imageEntities = new HashMap<>();
        }
        imageEntities.put(key, bitmap);
    }

    public String uploadMultiPart() {
        String result = "";

        try {
            MultipartEntity reqEntity = new MultipartEntity();
            if (imageEntities != null) {
                for (Map.Entry<String, Bitmap> entry : imageEntities.entrySet()) {
                    ByteArrayBody body = new ByteArrayBody(ImageUtils.getBytesFromBitmap(entry
                            .getValue()), ContentType.create("image/jpeg"),
                            System.currentTimeMillis() + ".jpg");
                    reqEntity.addPart(entry.getKey(), body);
                    LogUtils.d(TAG, "body key is " + entry.getKey() + ", " +
                            "body length is " + body.getContentLength());
                }
            }
            if (map != null) {
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    LogUtils.d(TAG, "add part for : " + entry.getKey() + ", " + entry.getValue());
                    if (!TextUtils.isEmpty(entry.getValue())) {
                        reqEntity.addPart(entry.getKey(), new StringBody(entry.getValue(),
                                Charset.forName("utf-8")));
                    }
                }
            }
            HttpResponse response = postClient(reqEntity);
            LogUtils.d(TAG, "response code is " + response.getStatusLine().getStatusCode());

            if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    InputStream in = resEntity.getContent();
                    result = getResult(in);
                    resEntity.consumeContent();
                }
            }
        } catch (ClientProtocolException e) {
            result = HTTP_ERROR;
            e.printStackTrace();
        } catch (IOException e) {
            result = HTTP_IO_ERROR;
            e.printStackTrace();
        } finally {
            try {
                client.getConnectionManager().shutdown();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return result;
    }


}